var canvas = document.getElementById('canvas'),
    context = canvas.getContext('2d'),

    CENTROID_RADIUS = 10,//表盘的中心小圆半径
    CENTROID_STROKE_STYLE = 'rgba(0, 0, 0, 0.5)',//小圆边的填充色
    CENTROID_FILL_STYLE = 'rgba(80, 190, 240, 0.6)',//小圆里面的填充色

    RING_INNER_RADIUS = 35,//内圆半径
    RING_OUTER_RADIUS = 55,//外圆半径

    ANNOTATIONS_FILL_STYLE = 'rgba(0, 0, 230, 0.9)',//表盘上面数字的颜色
    ANNOTATIONS_TEXT_SIZE = 12,//表盘上数字的大小

    TICK_WIDTH = 10,
    TICK_LONG_STROKE_STYLE = 'rgba(100, 140, 230, 0.9)',
    TICK_SHORT_STROKE_STYLE = 'rgba(100, 140, 230, 0.7)',

    TRACKING_DIAL_STROKING_STYLE = 'rgba(100, 140, 230, 0.5)',

    GUIDEWIRE_STROKE_STYLE = 'goldenrod',
    GUIDEWIRE_FILL_STYLE = 'rgba(250, 250, 0, 0.6)',

    circle = {
        x: canvas.width / 2,
        y: canvas.height / 2,
        radius: 150
    };

// Functions..........................................................

function drawGrid(color, stepx, stepy) {
    context.save()

    context.shadowColor = undefined;
    context.shadowOffsetX = 0;
    context.shadowOffsetY = 0;

    context.strokeStyle = color;
    context.fillStyle = '#ffffff';
    context.lineWidth = 0.5;
    context.fillRect(0, 0, context.canvas.width,
        context.canvas.height);

    for (var i = stepx + 0.5;
         i < context.canvas.width; i += stepx) {
        context.beginPath();
        context.moveTo(i, 0);
        context.lineTo(i, context.canvas.height);
        context.stroke();
    }

    for (var i = stepy + 0.5;
         i < context.canvas.height; i += stepy) {
        context.beginPath();
        context.moveTo(0, i);
        context.lineTo(context.canvas.width, i);
        context.stroke();
    }

    context.restore();
}
/**
 * 这里开始绘制
 */
function drawDial() {
    var loc = {x: circle.x, y: circle.y};

    drawCentroid();
    drawCentroidGuidewire(loc);

    drawRing();
    drawTickInnerCircle();
    drawTicks();
    drawAnnotations();
}
/**
 * 这里开始绘制中心的小圆
 */
function drawCentroid() {
    context.beginPath();
    context.save();
    context.strokeStyle = CENTROID_STROKE_STYLE;
    context.fillStyle = CENTROID_FILL_STYLE;
    context.arc(circle.x, circle.y,
        CENTROID_RADIUS, 0, Math.PI * 2, false);
    context.stroke();
    context.fill();
    context.restore();
}
/**
 * 这里开始绘制引导线
 * @param loc
 */
function drawCentroidGuidewire(loc) {
    var angle = -Math.PI / 4,
        radius, endpt;

    radius = circle.radius + RING_OUTER_RADIUS;

    if (loc.x >= circle.x) {
        endpt = {
            x: circle.x + radius * Math.cos(angle),
            y: circle.y + radius * Math.sin(angle)
        };
    }
    else {
        endpt = {
            x: circle.x - radius * Math.cos(angle),
            y: circle.y - radius * Math.sin(angle)
        };
    }

    context.save();

    context.strokeStyle = GUIDEWIRE_STROKE_STYLE;
    context.fillStyle = GUIDEWIRE_FILL_STYLE;

    context.beginPath();
    context.moveTo(circle.x, circle.y);
    context.lineTo(endpt.x, endpt.y);
    context.stroke();

    context.beginPath();
    context.strokeStyle = TICK_LONG_STROKE_STYLE;
    context.arc(endpt.x, endpt.y, 5, 0, Math.PI * 2, false);
    context.fill();
    context.stroke();

    context.restore();
}
/**
 * 开始绘制圆环
 */
function drawRing() {
    drawRingOuterCircle();

    context.strokeStyle = 'rgba(0, 0, 0, 0.1)';
    context.arc(circle.x, circle.y,
        circle.radius + RING_INNER_RADIUS,
        0, Math.PI * 2, false);

    context.fillStyle = 'rgba(100, 140, 230, 0.1)';
    context.fill();
    context.stroke();
}
/**
 * 绘制外圆并设置外圆的阴影
 */
function drawRingOuterCircle() {
    context.shadowColor = 'rgba(0, 0, 0, 0.7)';
    context.shadowOffsetX = 3,
        context.shadowOffsetY = 3,
        context.shadowBlur = 6,
        context.strokeStyle = TRACKING_DIAL_STROKING_STYLE;
    context.beginPath();
    context.arc(circle.x, circle.y, circle.radius +
    RING_OUTER_RADIUS, 0, Math.PI * 2, true);
    context.stroke();
}
/**
 * 绘制内圆 注意内圆的方向和外圆相反的呢哈
 */
function drawTickInnerCircle() {
    context.save();
    context.beginPath();
    context.strokeStyle = 'rgba(0, 0, 0, 0.1)';
    context.arc(circle.x, circle.y,
        circle.radius + RING_INNER_RADIUS - TICK_WIDTH,
        0, Math.PI * 2, false);
    context.stroke();
    context.restore();
}
/**
 * 绘制刻度
 * @param angle
 * @param radius
 * @param cnt
 */
function drawTick(angle, radius, cnt) {
    var tickWidth = cnt % 4 === 0 ? TICK_WIDTH : TICK_WIDTH / 2;

    context.beginPath();

    context.moveTo(circle.x + Math.cos(angle) * (radius - tickWidth),
        circle.y + Math.sin(angle) * (radius - tickWidth));

    context.lineTo(circle.x + Math.cos(angle) * (radius),
        circle.y + Math.sin(angle) * (radius));

    context.strokeStyle = TICK_SHORT_STROKE_STYLE;
    context.stroke();
}
/**
 * 计算绘制所有的刻度
 */
function drawTicks() {
    var radius = circle.radius + RING_INNER_RADIUS,
        ANGLE_MAX = 2 * Math.PI,
        ANGLE_DELTA = Math.PI / 64,
        tickWidth;

    context.save();

    for (var angle = 0, cnt = 0; angle < ANGLE_MAX;
         angle += ANGLE_DELTA, cnt++) {
        drawTick(angle, radius, cnt++);
    }

    context.restore();
}
/**
 * 绘制圆盘周边的数字
 */
function drawAnnotations() {
    var radius = circle.radius + RING_INNER_RADIUS;

    context.save();
    context.fillStyle = ANNOTATIONS_FILL_STYLE;
    context.font = ANNOTATIONS_TEXT_SIZE + 'px Helvetica';

    for (var angle = 0; angle < 2 * Math.PI; angle += Math.PI / 8) {
        context.beginPath();
        context.fillText((angle * 180 / Math.PI).toFixed(0),
            circle.x + Math.cos(angle) * (radius - TICK_WIDTH * 2),
            circle.y - Math.sin(angle) * (radius - TICK_WIDTH * 2));
    }
    context.restore();
}

// Initialization....................................................

context.shadowOffsetX = 2;
context.shadowOffsetY = 2;
context.shadowBlur = 4;//shadowBlur 属性设置或返回阴影的模糊级数

context.textAlign = 'center';
context.textBaseline = 'middle';
drawGrid('lightgray', 10, 10);//绘制网格
drawDial();
